package com.droidclaimsurveyor.activity;

import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.droidclaimsurveyor.R;
import com.droidclaimsurveyor.bl.CarImageBl;
import com.droidclaimsurveyor.bl.DroidClaimBlService;
import com.droidclaimsurveyor.bl.ServeyorClaimInfoBl;
import com.droidclaimsurveyor.dto.ClaimIdResultBlDto;
import com.droidclaimsurveyor.dto.ClaimInfoBlDto;
import com.droidclaimsurveyor.dto.UpdateClaimInfoBlDto;
import com.droidclaimsurveyor.dto.UploadFileListDto;
import com.droidclaimsurveyor.dto.UploadFileResultDto;
import com.droidclaimsurveyor.helper.asyntask.ICompleteListener;
import com.droidclaimsurveyor.helper.utils.FileHandle;
import com.droidclaimsurveyor.model.CarImageModel;
import com.droidclaimsurveyor.model.ClaimInfoModel;

public class ClaimWorkActivity extends Activity implements ICompleteListener{
	private Camera mCamera;
	private CameraPreview mCameraPreview;
	private FrameLayout cameraPreviewFL;
	private Button captureBtn;
	private boolean isFreeze;

	private ImageView imagePreviewIV;
	private ImageButton deleteImageBtn;
	private ImageButton sendImageBtn;

	private List<CarImageModel> dataList;
	private ImageListAdapter listAdapter;
	private ListView listView;

	private ImageView claimReportIV;
	private CarImageModel claimReportData;

	private int currentImageItem;
	
	private final String MAIN_ACTIVITY_REQUEST = "101"; //when click menu
	
	private String getLastClaimInfoTaskId;
	private String getAllCarImageTaskId;
	private String updateClaimTaskId;
	private String uploadFileTaskId;
	private ClaimInfoModel claimInfo;
	private String requestId;
	private TextView claimReportNoTV;
	

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_claim_work);

		// camera pane
		cameraPreviewFL = (FrameLayout) findViewById(R.id.camera_preview);
		captureBtn = (Button) findViewById(R.id.button_capture);
		captureBtn.setOnClickListener(onClickCaptureButton);

		// image preview pane
		imagePreviewIV = (ImageView) findViewById(R.id.preview_imageview);
		deleteImageBtn = (ImageButton) findViewById(R.id.delete_button);
		deleteImageBtn.setOnClickListener(onClickDeleteButton);
		sendImageBtn = (ImageButton) findViewById(R.id.send_btn);
		sendImageBtn.setOnClickListener(onClickSendButton);

		// Initialize List View
		dataList = new ArrayList<CarImageModel>();
		for(int i=0; i<5; i++){
			CarImageModel model = new CarImageModel();
			dataList.add(model);
		}
		listAdapter = new ImageListAdapter(this, R.layout.imageitem_layout,dataList);
		listView = (ListView) findViewById(R.id.carimage_listview);
		listView.setAdapter(listAdapter);
		listView.setClickable(true);
		listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

	        @Override
	        public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) {
	        	handleSelectImage(position);
	        }
	    });
		registerForContextMenu(listView);

		claimReportIV = (ImageView) findViewById(R.id.claim_report_imageview);
		claimReportIV.setOnClickListener(onClickClaimReportImage);
		claimReportData = new CarImageModel();

		currentImageItem = 0;		
		
		ServeyorClaimInfoBl serveyorClaimInfoBl = new ServeyorClaimInfoBl(this);
		claimInfo = new ClaimInfoModel();
				
		claimReportNoTV = (TextView) findViewById(R.id.claimreport_listview);
		//Get IntenExtras
		Bundle extras = getIntent().getExtras();
		if (extras != null) {
			requestId = extras.getString("request_id");
			if(requestId.equals(MAIN_ACTIVITY_REQUEST)){
				/*
				 * from main menu get lasted record form DB
				 */
				getLastClaimInfoTaskId = serveyorClaimInfoBl.GetLastClaimInfo();
			}
		}
	}
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.claim_work, menu);
		return true;
	}

	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.carimage_contextmenu, menu);

		super.onCreateContextMenu(menu, v, menuInfo);
	}

	@Override
	public boolean onContextItemSelected(MenuItem item) {
		AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
				.getMenuInfo();
		if (item.getItemId() == R.id.delete_menu) {
			handleDeleteImage(info.position);
		} else if (item.getItemId() == R.id.select_menu) {
			handleSelectImage(info.position);
		}

		return super.onContextItemSelected(item);
	}
	
	@Override
	protected void onResume() {
		super.onResume();
		
		handleSelectImage(currentImageItem);
		long claimId = claimInfo.getId();
		if(claimId>0){
			CarImageBl carImageBl = new CarImageBl(this);
			getAllCarImageTaskId = carImageBl.GetAllCarImage(Long.toString(claimId));
			
			int claimDocId = claimInfo.getClaimDocId();
			if(claimDocId>0){
				claimReportNoTV.setText(claimDocId + "");
			}
		}
	}

	@Override
	protected void onPause() {
		super.onPause();
		closeCamera();
	}

	private void openCamera() {
		try {
			closeCamera();

			Camera camera = Camera.open();
			CameraPreview cameraPreview = new CameraPreview(this, camera);
			FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
			preview.addView(cameraPreview);
			mCamera = camera;
			mCameraPreview = cameraPreview;
			
			isFreeze = false;
		} catch (Exception ex) {
			Toast.makeText(this, ex.getMessage(), Toast.LENGTH_LONG).show();
		}
	}
	
	private void startCamera(){
		if(isFreeze){
			mCamera.startPreview();
			isFreeze = false;
		}
	}

	private void closeCamera() {
		if (mCamera == null) {
			return;
		}
		mCameraPreview.surfaceDestroyed(null);
		mCamera = null;
		mCameraPreview = null;
	}

	public View.OnClickListener onClickCaptureButton = new View.OnClickListener() {

		@Override
		public void onClick(View v) {
			if (isFreeze) {
				mCamera.startPreview();
				isFreeze = false;
			} else {
				mCamera.takePicture(null, null, mPicture);
			}
		}
	};

	public View.OnClickListener onClickDeleteButton = new View.OnClickListener() {

		@Override
		public void onClick(View v) {
			handleDeleteImage(currentImageItem);
		}
	};
	
	public View.OnClickListener onClickSendButton = new View.OnClickListener() {

		@Override
		public void onClick(View v) {
			DroidClaimBlService bl = new DroidClaimBlService(ClaimWorkActivity.this);
			String fileName = claimReportData.getImgPath();
			String filePath = FileHandle.getFilePath(fileName);
			File claimReport = new File(filePath);
			ArrayList<File> listFile = new ArrayList<File>();
			listFile.add(claimReport);
			UploadFileListDto param = new UploadFileListDto();
			param.setListFiles(listFile);
			uploadFileTaskId = bl.UploadFile(param);
		}
	};

	PictureCallback mPicture = new PictureCallback() {
		@Override
		public void onPictureTaken(byte[] data, Camera camera) {
			try {
				String filename = FileHandle.getUnigueImageFileName("");
				String filePath = FileHandle.getFilePath(filename);
				if (filePath == null) {
					throw new Exception("Cannot crate file");
				}

				File pictureFile = new File(filePath);
				FileOutputStream fos = new FileOutputStream(pictureFile);
				fos.write(data);
				fos.close();
				isFreeze = true;
				
				CarImageModel model = null;
				if (currentImageItem == -1) {
					model = claimReportData;
					model.setImgPath(filename);
					Bitmap imageBM = FileHandle.getImage(filename);
					model.setImage(imageBM);
					claimReportIV.setImageBitmap(imageBM);
				} else {
					model = dataList.get(currentImageItem);
					model.setImgPath(filename);
					Bitmap imageBM = FileHandle.getImage(filename);
					model.setImage(imageBM);
					listAdapter.notifyDataSetChanged();
				}
				
				CarImageBl bl = new CarImageBl(ClaimWorkActivity.this);
				long rowId = model.getRowId();
				if(rowId<=0){
					model.setClaim_Id((int)claimInfo.getId());
					model.setId(currentImageItem);
					model.setRowId(rowId);
					rowId = bl.addCarImage(model);

				}else{
					bl.updateCarImage(rowId, model);
				}
			} catch (Exception ex) {
				Toast.makeText(ClaimWorkActivity.this, ex.getMessage(),Toast.LENGTH_LONG).show();
			}
		}
	};

	public View.OnClickListener onClickClaimReportImage = new View.OnClickListener() {
		@Override
		public void onClick(View v) {
			currentImageItem = -1;
			handleSelectImage(currentImageItem);
		}
	};
	
	
	public void handleSelectImage(int itemNo) {
		CarImageModel model = null;
		currentImageItem = itemNo;
		if (itemNo == -1) {
			model = claimReportData;
		} else {
			model = dataList.get(itemNo);
		}
		
		Bitmap image = model.getImage();
		if (image != null) {
			switchToImagePane(image);
		} else {
			switchToCameraPane();
		}
	}

	public void handleDeleteImage(int itemNo) {
		CarImageModel model = null;
		currentImageItem = itemNo;

		String filename = null;
		if (itemNo == -1) {
			model = claimReportData;
			filename = model.getImgPath();
			model.setImgPath("");
			model.setImage(null);
			Drawable d = getResources().getDrawable(R.drawable.gallery);
			claimReportIV.setImageDrawable(d);
		} else {
			model = dataList.get(itemNo);
			filename = model.getImgPath();
			model.setImgPath("");
			model.setImage(null);
			listAdapter.notifyDataSetChanged();
		}

		File file = new File(FileHandle.getFilePath(filename));
		if (file.exists()) {
			file.delete();
		}
		
		switchToCameraPane();
	}

	public void switchToImagePane(Bitmap image) {
		cameraPreviewFL.setVisibility(View.GONE);
		captureBtn.setVisibility(View.GONE);
		imagePreviewIV.setVisibility(View.VISIBLE);
		
		imagePreviewIV.setImageBitmap(image);
		if (currentImageItem == -1) {
			sendImageBtn.setVisibility(View.VISIBLE);
			deleteImageBtn.setVisibility(View.GONE);
		}else{
			sendImageBtn.setVisibility(View.GONE);
			deleteImageBtn.setVisibility(View.VISIBLE);
		}
	}

	public void switchToCameraPane() {
		cameraPreviewFL.setVisibility(View.VISIBLE);
		captureBtn.setVisibility(View.VISIBLE);
		imagePreviewIV.setVisibility(View.GONE);
		deleteImageBtn.setVisibility(View.GONE);
		sendImageBtn.setVisibility(View.GONE);
		
		if(mCamera!=null){
			startCamera();
		}else{
			openCamera();
		}
	}
	
	@Override
	public void onTaskCompleteSuccess(String taskId, Object result) {
		try{
			if(taskId.equals(getLastClaimInfoTaskId)){
				List<ClaimInfoModel> dtoList = (List<ClaimInfoModel>) result;
				if(dtoList==null || dtoList.size()<=0){
					throw new Exception("Error : empty ClaimInfoModel in database");
				}
				claimInfo = dtoList.get(0);
				long claimId = claimInfo.getId();
				
				CarImageBl carImageBl = new CarImageBl(this);
				getAllCarImageTaskId = carImageBl.GetAllCarImage(Long.toString(claimId));
				
			}else if(taskId.equals(getAllCarImageTaskId)){
				if(result!=null){
					List<CarImageModel> dtoList = (List<CarImageModel>) result;
					for (CarImageModel carImageModel : dtoList) {
						String filename = carImageModel.getImgPath();
						long imageId = carImageModel.getId();
						if(imageId==-1){
							//claimWorkModel.setClaimReportImgPath(filename);
							Bitmap bm = FileHandle.getImage(filename);
							carImageModel.setImage(bm);						
							claimReportData = carImageModel;
						}else{
							Bitmap bm = FileHandle.getImage(filename);
							carImageModel.setImage(bm);
							dataList.set((int)imageId, carImageModel);
						}
						
						listAdapter.notifyDataSetChanged();
						handleSelectImage(currentImageItem);
					}
				}
			}else if(taskId.equals(updateClaimTaskId)){
				if(result!=null){
					ClaimIdResultBlDto dto = (ClaimIdResultBlDto) result;
					int claimDocId = dto.getClaimNumber();
					claimInfo.setClaimDocId(claimDocId);
					claimReportNoTV.setText(claimDocId+"");
				}
			}else if(taskId.equals(uploadFileTaskId)){
				if(result!=null){
					UploadFileResultDto dto = (UploadFileResultDto) result;
					if (dto.isResult()) {
						String filePath = dto.getListFiles().get(0);
						
						DroidClaimBlService bl = new DroidClaimBlService(ClaimWorkActivity.this);
						UpdateClaimInfoBlDto param = new UpdateClaimInfoBlDto();
						param.setClaimId((int)claimInfo.getId());
						param.setSessionId(MainActivity.getSessionId());
						param.setClaimDocImage(filePath);
						updateClaimTaskId = bl.UpdateClaim(param);

						dto.getListFiles().get(0);
					}
				}
			}
		}catch(Exception ex){
			Toast.makeText(this, ex.getMessage(), Toast.LENGTH_LONG).show();
		}
		
	}

	@Override
	public void onTaskFailed(String taskId, Exception cause) {
		Toast.makeText(this, "Error : in call " + taskId, Toast.LENGTH_LONG).show();	
	}
}
